﻿// Copyright (c) 2009 Kjetil Eraker Samuelsen
// This source is subject to the Microsoft Public License.
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
// All other rights reserved.

using System;
using System.Collections.Generic;

using OOutlook = Microsoft.Office.Interop.Outlook;


namespace Ksamuelsen.Office.Outlook {
    /// <summary>
    /// Contains a useful methods for accessing various Outlook objects more easily
    /// </summary>
    /// <remarks>
    /// This class contains methods to access Outlook objects more easily. The class and all it's methods are static - it must be
    /// initialized before first use and disposed before the end of the program.
    /// </remarks>
    public static class OutlookManager {
        private static OOutlook.Application _application;
        private static List<OptionPage>     _optionPages = new List<OptionPage>();

        public static void Init(OOutlook.Application app) {
            _application = app;
        }

        public static void Dispose() {
            if (_optionPages .Count > 0)
                _application.OptionsPagesAdd -= new OOutlook.ApplicationEvents_11_OptionsPagesAddEventHandler(OnOptionPagesAdd);

            _optionPages.Clear();

            _optionPages = null;
            _application = null;
        }

        public static OOutlook.Application Application {
            get { return _application; }
        }

        public static OOutlook.Categories Categories {
            get {
                return Application.Session.Categories;
            }
        }

        // ----------------------------------------------------------------------------------------------
        // -- Property pages
        // ----------------------------------------------------------------------------------------------

        public static void AddOptionPage(Type page, string tabTitle) {
            if (_optionPages.Count == 0)
                _application.OptionsPagesAdd += new OOutlook.ApplicationEvents_11_OptionsPagesAddEventHandler(OnOptionPagesAdd);
            
            _optionPages.Add(new OptionPage(page, tabTitle));
        }


        private static void OnOptionPagesAdd(OOutlook.PropertyPages pages) {
            if (_optionPages.Count == 0)
                return;

            foreach (OptionPage page in _optionPages) {
                OOutlook.PropertyPage pg = page.Page;

                pages.Add(page.Page, page.Title);
            }

        }




        // ----------------------------------------------------------------------------------------------
        // -- Store/Folder related
        // ----------------------------------------------------------------------------------------------

        public static OutlookFolderRef[] GetFolders(OOutlook.OlItemType itemType) {
            OOutlook.Stores stores = Application.Session.Stores;
            List<OutlookFolderRef> refs = new List<OutlookFolderRef>();

            foreach (OOutlook.Store store in stores) {
                string str = store.DisplayName;
                if (!store.ExchangeStoreType.Equals(OOutlook.OlExchangeStoreType.olExchangePublicFolder)) {
                    GetFolders(refs, (OOutlook.Folder)store.GetRootFolder(), itemType);
                }
            }
            return refs.ToArray();
        }

        private static void GetFolders(List<OutlookFolderRef> refs, OOutlook.Folder root, OOutlook.OlItemType itemType) {
            if ((root.Folders == null) || (root.Folders.Count == 0)) 
                return;

            foreach (OOutlook.Folder folder in root.Folders) {
                string name = folder.Name;
                string description = folder.Description;
                if (folder.DefaultItemType.Equals(itemType))
                    refs.Add(new OutlookFolderRef(folder.StoreID, folder.Store.DisplayName, folder.EntryID, folder.Name));
                GetFolders(refs, folder, itemType);
            }
        }

        // ----------------------------------------------------------------------------------------------
        // -- Journal related 
        // ----------------------------------------------------------------------------------------------

        public static OutlookFolderRef[] GetJournalFolders() {
            return GetFolders(OOutlook.OlItemType.olJournalItem);
        }

        public static OutlookFolderRef GetDefaultJournalFolder() {
            OOutlook.Folder folder = (OOutlook.Folder)Application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderJournal);
            if (folder == null)
                return null;
            return new OutlookFolderRef(folder.StoreID, folder.Store.DisplayName, folder.EntryID, folder.Name);
        }


        public static OOutlook.JournalItem CreateJournal() {
            return (OOutlook.JournalItem)Application.CreateItem(OOutlook.OlItemType.olJournalItem);
        }

        public static OOutlook.JournalItem CreateJournal(OutlookFolderRef fref) {
            return fref.Folder.Items.Add(OOutlook.OlItemType.olJournalItem) as OOutlook.JournalItem;
        }

        private class OptionPage {
            private Type   _type;
            private string _title;

            public OptionPage(Type type, string title) {
                _type  = type;
                _title = title;
            }

            public string Title {
                get {
                    return _title;
                }
            }

            public OOutlook.PropertyPage Page {
                get {
                    return Activator.CreateInstance(_type) as OOutlook.PropertyPage;
                }
            }

        }


    }
}
